// 资源生成器, 根据项目源代码去更新"main.go"的文件内容

package main

import (
	"api/common"
	"api/common/logger"
	"fmt"
	"go/parser"
	"go/token"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

func main() {
	controllers := make([]string, 0)
	routes := make([]string, 0)

	gofiles := getFilelist(common.CurDir + "/src")
	for fileIndex, gofile := range gofiles {
		fset := token.NewFileSet()
		fileComment, err := parser.ParseFile(fset, gofile, nil, parser.ParseComments)
		if err != nil {
			logger.Fatal("Error while parsing router.go: %s", err)
		}

		if fileComment.Comments != nil {
			tagName := ""
			controller := ""
			commentIndex := 0
			for _, group := range fileComment.Comments {
				if strings.HasPrefix(group.Text(), "@TagName") { //标签解析
					for _, comment := range strings.Split(group.Text(), "\n") {
						if strings.HasPrefix(comment, "@TagName") {
							tagName = strings.TrimLeft(comment, "@TagName")
							tagName = strings.Trim(tagName, " ")
						}

						if strings.HasPrefix(comment, "@Controller") {
							controller = strings.TrimLeft(comment, "@Controller")
							controller = strings.Trim(controller, " ")
						}
					}

					if tagName != "" && controller != "" {
						controller := fmt.Sprintf("%s%s := new(%s.%s)", fileComment.Name, controller, fileComment.Name, controller)
						controllers = append(controllers, controller)
					}
				} else if strings.HasPrefix(group.Text(), "@Title") && controller != "" {
					title := ""
					desc := ""
					param := ""
					route := ""
					method := ""
					for _, comment := range strings.Split(group.Text(), "\n") {
						if strings.HasPrefix(comment, "@Title") {
							title = strings.TrimLeft(comment, "@Title")
							title = strings.Trim(title, " ")
						}
						if strings.HasPrefix(comment, "@Desc") {
							desc = strings.TrimLeft(comment, "@Desc")
							desc = strings.Trim(desc, " ")
						}
						if strings.HasPrefix(comment, "@Param") {
							param = strings.TrimLeft(comment, "@Param")
							param = strings.Trim(param, " ")
							//	param = strings.Replace(param,"\"","\"")
						}
						if strings.HasPrefix(comment, "@Route") {
							route = strings.TrimLeft(comment, "@Route")
							route = strings.Trim(route, " ")
						}
						if strings.HasPrefix(comment, "@Method") {
							method = strings.TrimLeft(comment, "@Method")
							method = strings.Trim(method, " ")
							method = strings.ToUpper(method)
						}
					}

					urlControl := strings.Split(route, "-->")

					if len(urlControl) == 2 {
						url := strings.Trim(urlControl[0], " ")
						if strings.HasPrefix(url, "/") {
							url = fileComment.Name.Name + url
						} else {
							url = fileComment.Name.Name + "/" + url
						}
						code := fmt.Sprintf("{\"%03x_%03x\", \"%s\", \"%s\", \"%s\", \"%s\", %s%s.%s, `%s`, \"%s\"},", fileIndex, commentIndex, fileComment.Name, title, url, method, fileComment.Name, controller, strings.Trim(urlControl[1], " "), param, desc)
						routes = append(routes, code)
						commentIndex++
					}
				}
			}
		}
	}

	fmt.Println(strings.Join(controllers, "\n"))
	fmt.Println(strings.Join(routes, "\n"))
	editMainFile(controllers, routes)
}

// 项目目录下所有控制类文件
func getFilelist(path string) []string {
	files := make([]string, 0)
	err := filepath.Walk(path, func(path string, f os.FileInfo, err error) error {
		if f.IsDir() {
			return nil
		}

		if !strings.Contains(path, "common") && !strings.Contains(path, "models") {
			files = append(files, path)
		}

		return nil
	})

	if err != nil {
		logger.Error("遍历目录", path, "发生错误:", err)
		return nil
	}
	return files
}

// 覆写主文件
func editMainFile(controllers, routes []string) {
	file, err := os.OpenFile(common.CurDir+"/main.go", os.O_RDWR|os.O_APPEND|os.O_CREATE, os.ModeType)
	if err != nil {
		logger.Error("打开主文件发生错误", err)
		return
	}

	content, err := ioutil.ReadAll(file)
	_ = file.Close()
	if err != nil {
		logger.Error("读取主文件发生错误", err)
		return
	}

	code := string(content)
	codeArr := strings.Split(code, "/*系统控制器*/")
	code = codeArr[0] + "/*系统控制器*/\n	" + strings.Join(controllers, "\n	") + "\n	/*系统控制器*/" + codeArr[2]

	codeArr = strings.Split(code, "	/*系统资源*/")
	code = codeArr[0] + "	/*系统资源*/\n		" + strings.Join(routes, "\n		") + "\n		/*系统资源*/" + codeArr[2]

	ioutil.WriteFile(common.CurDir+"/main.go", []byte(code), 0)
}
